`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:     Z-Control
// Engineer:    Lu Shengkang
// 
// Create Date:    08:58:56 02/22/2019 
// Design Name: 
// Module Name:    dec_8b10b 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module  enc_8b10b(
    input   wire            clk,
    input   wire            rst,
    input   wire            KI,
    input   wire    [7:0]   data_in_8b,
    output  reg     [9:0]   data_out_10b
);
    reg     XLRESET, LRESET;                //-- Local synchronized RESET
    //wire    L40, L04, L13, L31, L22         //-- Figure 3 Signals
    reg     F4, G4, H4, K4, S;//, FNEG;        //-- Figure 4 Signals 
    //reg     PD1S6, ND1S6, PD0S6, ND0S6;     //-- Figure 5 Signals 
    //reg     ND1S4, ND0S4, PD1S4, PD0S4;     //-- ...Figure 5
    //reg     COMPLS4, COMPLS6, NDL6;         //-- Figure 6 Signals 
    //reg     PDL6, LPDL6, PDL4, LPDL4;       //-- Figure 6
    reg     LPDL6, LPDL4;
    //reg     NAO, NBO, NCO, NDO, NEO, NIO;   //-- Figure 7 Signals
    //reg     NFO, NGO, NHO, NJO, SINT;       //-- Figure 8
    
    reg     AO, BO, CO, DO, EO, IO, FO, GO, HO, JO;
    
    wire AI = data_in_8b[0] ;
    wire BI = data_in_8b[1] ;
    wire CI = data_in_8b[2] ;
    wire DI = data_in_8b[3] ;
    wire EI = data_in_8b[4] ;
    wire FI = data_in_8b[5] ;
    wire GI = data_in_8b[6] ;
    wire HI = data_in_8b[7] ;
       
   //-- PROCESS: SYNCRST; Synchronize and delay RESET one clock for startup
    always  @(posedge   clk)
    begin
        XLRESET <=  rst;
    end 
	 
	 always	@(negedge	clk)
	 begin
		  LRESET  <=  XLRESET;
	 end
	 
	//--
	//-- 5b Input Function (Reference: Figure 3)
	//--
	
    //-- Four 1's
    wire    L40 = AI & BI & CI & DI ;           //-- 1,1,1,1
    //-- Four 0's
    wire    L04 = ! AI & ! BI & ! CI & ! DI ;   //-- 0,0,0,0
    //-- One 1 and three 0's
    wire    L13 =	(! AI & ! BI & ! CI & DI)		//-- 0,0,0,1
						| (! AI & ! BI & CI & ! DI)	//-- 0,0,1,0		
						| (! AI & BI & ! CI & ! DI)	//-- 0,1,0,0
						| (AI & ! BI & ! CI & ! DI) ;	//-- 1,0,0,0
    //-- Three 1's and one 0
    wire    L31 =	(AI & BI & CI & ! DI)			//-- 1,1,1,0	
						| (AI & BI & ! CI & DI)			//-- 1,1,0,1
						| (AI & ! BI & CI & DI)			//-- 1,0,1,1
						| (! AI & BI & CI & DI) ;		//-- 0,1,1,1
    //-- Two 1's and two 0's
    wire    L22 =	(! AI & ! BI & CI & DI)			//-- 0,0,1,1
						| (! AI & BI & CI & ! DI)		//-- 0,1,1,0
						| (AI & BI & ! CI & ! DI)		//-- 1,1,0,0
						| (AI & ! BI & ! CI & DI)		//-- 1,0,0,1
						| (! AI & BI & ! CI & DI)		//-- 0,1,0,1
						| (AI & ! BI & CI & ! DI) ;	//-- 1,0,1,0
    
	//--
   //-- 3b Input Function (Reference: Figure 4)
	//--
	
    //-- PROCESS: FN3B; Latch 3b and K inputs
    always  @(negedge   clk)
    begin
      F4 <= FI ;
      G4 <= GI ;
		H4 <= HI ;
		K4 <= KI ;
    end     
	 
	//-- PROCESS: FNS; Create and latch "S" function    
    always  @(posedge	clk)
    begin
        if(LRESET)begin
            S <= 'b0 ;
        end 
        else begin
            S <= (PDL6 & L31 & DI & ! EI)
			    | (NDL6 & L13 & EI & ! DI) ;
        end
    end
    
    //-- Intermediate term for "F4 is Not Equal to G4"
    wire    FNEG = F4^G4;
    
	//--
	//-- Disparity Control - Figure 5
	//--    
    
    wire    PD1S6 = (! L22 & ! L31 & ! EI)
							| (L13 & DI & EI) ;
    wire    ND1S6 = (L31 & ! DI & ! EI)
							| (EI & ! L22 & ! L13)
							| K4 ;
    wire    PD0S6 = (! L22 & ! L13 & EI)
							| K4 ;
    wire    ND0S6 = (! L22 & ! L31 & ! EI)
							| (L13 & DI & EI) ;
    wire    ND1S4 = (F4 & G4);
    wire    ND0S4 = (! F4 & ! G4);
    wire    PD1S4 = (! F4 & ! G4)
							| (FNEG & K4) ;
    wire    PD0S4 = (F4 & G4 & H4) ;
		
	//--
	//-- Disparity Control - Figure 6
	//--
			
    wire    PDL6 = (PD0S6 & ! COMPLS6)
		         | (COMPLS6 & ND0S6)
		        	| (! ND0S6 & ! PD0S6 & LPDL4) ;	
    wire    NDL6 = ! PDL6 ;
    wire    PDL4 = (LPDL6 & ! PD0S4 & ! ND0S4)
			        | (ND0S4 & COMPLS4)
			        | (! COMPLS4 & PD0S4) ;
	
	//-- PROCESS: CMPLS4; Disparity determines complimenting S4
    always  @(posedge	clk)
    begin
        if(LRESET)begin
            LPDL6 <= 'b0 ;
        end 
        else    begin
            LPDL6 <= PDL6 ; 
        end 
    end 
    
    wire    COMPLS4 = (PD1S4 & ! LPDL6)^(ND1S4 & LPDL6) ;
			
    //-- PROCESS: CMPLS6; Disparity determines complimenting S6
    always  @(negedge	clk)
    begin
        if(LRESET)begin
            LPDL4 <= 'b0 ;
        end 
        else    begin
            LPDL4 <= PDL4 ;
        end 
    end 
    
    wire    COMPLS6 = (ND1S6 & LPDL4) ^ (PD1S6 & ! LPDL4) ;
	
	//--
	//-- 5b/6b Encoder - Figure 7
	//--
	
	//-- Logic for non-complimented (Normal) A,B,C,D,E,I outputs
    wire    NAO = AI ;
    wire    NBO = L04	
						| (BI & ! L40) ;
    wire    NCO = CI	
						| L04	
						| (L13 & DI & EI) ;
    wire    NDO = (DI & ! L40) ;
    wire    NEO = (EI & ! (L13 & DI & EI))
                   | (L13 & ! EI) ; 
    wire    NIO = (L22 & ! EI)
		            | (L04 & EI)
		            | (L13 & ! DI & EI)
		            | (L40 & EI) 
		            | (L22 & KI) ;
 
 	//-- PROCESS: ENC5B6B; Generate and latch LS 6 encoded bits 
    always  @(posedge	clk)
    begin
        if(LRESET)begin
         AO <= 'b0 ;
			BO <= 'b0 ;
			CO <= 'b0 ;
			DO <= 'b0 ;
			EO <= 'b0 ;
			IO <= 'b0 ;
        end 
        else    begin
         AO <= COMPLS6 ^ NAO ;	//-- Least significant bit 0
			BO <= COMPLS6 ^ NBO ;
			CO <= COMPLS6 ^ NCO ;
			DO <= COMPLS6 ^ NDO ;
			EO <= COMPLS6 ^ NEO ;
			IO <= COMPLS6 ^ NIO ;	//-- Most significant bit 6
        end 
    end 
	
	//--
	//-- 3b/4b Encoder - Figure 8
	//--
	
	//-- Logic for the non-complimented F,G,H,J outputs 	
    wire   SINT = (S & F4 & G4 & H4)
		           | (K4 & F4 & G4 & H4) ;
	wire    NFO  = (F4 & ! SINT) ;
	wire    NGO  = G4 
		           | (! F4 & ! G4 & ! H4) ;
	wire    NHO  = H4 ;
	wire    NJO  = SINT
		           | (FNEG & ! H4) ;	
		         
	//-- PROCESS: ENC3B4B; Generate and latch MS 4 encoded bits 	  	        
    always  @(negedge   clk)
    begin
       if(LRESET) begin
         FO <= 'b0 ;
			GO <= 'b0 ;
			HO <= 'b0 ;
			JO <= 'b0 ;
        end 
        else begin
         FO <= COMPLS4 ^ NFO ;	//-- Least significant bit 7
			GO <= COMPLS4 ^ NGO ;
			HO <= COMPLS4 ^ NHO ;
			JO <= COMPLS4 ^ NJO ;	//-- Most significant bit 10
        end 
    end 
    
	always	@(posedge	clk)
	begin
		if(LRESET)begin
			data_out_10b[0] =  'b0 ;
			data_out_10b[1] =  'b0 ;
			data_out_10b[2] =  'b0 ;
			data_out_10b[3] =  'b0 ;
			data_out_10b[4] =  'b0 ;
			data_out_10b[5] =  'b0 ;
			data_out_10b[6] =  'b0 ;
			data_out_10b[7] =  'b0 ;
			data_out_10b[8] =  'b0 ;
			data_out_10b[9] =  'b0 ;
		end
		else	begin
			data_out_10b[0] =  AO ;
			data_out_10b[1] =  BO ;
			data_out_10b[2] =  CO ;
			data_out_10b[3] =  DO ;
			data_out_10b[4] =  EO ;
			data_out_10b[5] =  IO ;
			data_out_10b[6] =  FO ;
			data_out_10b[7] =  GO ;
			data_out_10b[8] =  HO ;
			data_out_10b[9] =  JO ;
		end 
	end
endmodule   